############################################################
# CMake file for NatusVerse makefile generation            #
# Copyright (C) 2013 Florian Dang <florian.coin@gmail.com> #
############################################################

cmake_minimum_required(VERSION 2.6.4)

project(natusverse)

set(NATUSVERSE_VERSION_MAJOR 0)
set(NATUSVERSE_VERSION_MINOR 1)

message(STATUS "${PROJECT_NAME} v${NATUSVERSE_VERSION_MAJOR}.${NATUSVERSE_VERSION_MINOR}")

IF(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
    SET(WINDOWS ON)
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Windows")

########################
# SET CONFIG ON OR OFF # Check below if you need to turn ON or OFF anything
########################

# remark : do not forget to set ENABLE_DEBUG_FLAGS and ENABLE_PROFILING OFF for faster results
option(ENABLE_OPTIMIZE_FLAGS   "Enable optimizing FLAGS (default:ON)" ON)

option(ENABLE_DEBUG_FLAGS      "Enable Debugging FLAGS (default:OFF)" OFF)

option(ENABLE_PROFILING        "Enable GProf profiling FLAGS (default:OFF)" OFF)

# Warning ! If set to ON this option forces ENABLE_DEBUG_FLAGS to ON and ENABLE_OPTIMIZE_FLAGS to OFF
option(ENABLE_DEBUG_FLAGS_FULL "Enable Full Debugging FLAGS (GCC only) (default:OFF)"  OFF)

option(ENABLE_DEBUG_OUTPUT     "Enable Debugging output (default:OFF)" OFF)

# Warning ! Cannot have both TBB and OMP enabled
option(ENABLE_OMP              "Enable OpenMP for multithreading (default:ON)"  ON)

# Warning ! If set to ON this option forces ENABLE_OMP to OFF
option(ENABLE_TBB              "Enable Intel TBB for multithreading (default:OFF)"  OFF)

option(CMAKE_VERBOSE_MAKEFILE  "Verbosity for printing make rules (default:OFF)" OFF)

option(ENABLE_FMOD             "FMOD sound library (default:ON)" ON)

##############
# END CONFIG #
##############

set (EXECUTABLE_OUTPUT_PATH bin/${CMAKE_BUILD_TYPE})

# configure a header file to pass some of the CMake settings to the source code
configure_file(
	"${PROJECT_SOURCE_DIR}/config.h.in"
	"${PROJECT_BINARY_DIR}/config.h"
)

### REQUIREMENTS ###

if (CMAKE_COMPILER_IS_GNUCC)
	execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
	if(GCC_VERSION VERSION_GREATER 4.2 OR GCC_VERSION VERSION_EQUAL 4.2)
		message(STATUS "gcc ${GCC_VERSION} >= 4.2 [OK]")
	 else ()
		message(FATAL_ERROR "gcc ${GCC_VERSION}. Please ugprade to gcc >= 4.2.")
	endif ()
endif (CMAKE_COMPILER_IS_GNUCC)

# Module path for other .cmake
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/;${CMAKE_MODULE_PATH}")

find_package(SDL REQUIRED)
include_directories(${SDL_INCLUDE_DIR})

# find_package(EXPAT REQUIRED)
# include_directories(${EXPAT_INCLUDE_DIR})

if (ENABLE_DEBUG_FLAGS_FULL)
	set(ENABLE_DEBUG_FLAGS ON)
	set(ENABLE_OPTIMIZE_FLAGS OFF)
endif (ENABLE_DEBUG_FLAGS_FULL)

# Finding Intel Threading Building Blocks
if(ENABLE_TBB)
	find_package(TBB)
	if(NOT TBB_FOUND)
	    message(STATUS "TBB not found - OpenMP will be used.")
	    set(ENABLE_TBB OFF)
	else(NOT TBB_FOUND)
		message(STATUS "TBB found thus overriding OpenMP")
		set(ENABLE_OMP OFF)
		include_directories(${TBB_INCLUDE_DIRS})
		link_directories(${TBB_LIBRARIES})
	endif(NOT TBB_FOUND)
endif(ENABLE_TBB)

message(STATUS "DEBUG OUTPUT ${ENABLE_DEBUG_OUTPUT}")
message(STATUS "DEBUG FLAGS ${ENABLE_DEBUG_FLAGS}")
message(STATUS "DEBUG FLAGS FULL ${ENABLE_DEBUG_FLAGS_FULL}")
message(STATUS "PROFILING ${ENABLE_PROFILING}")
message(STATUS "OPTIMIZE FLAGS ${ENABLE_OPTIMIZE_FLAGS}")
message(STATUS "OpenMP ${ENABLE_OMP}")
message(STATUS "Intel TBB ${ENABLE_TBB}")
message(STATUS "FMOD ${ENABLE_FMOD}")

### SET FLAGS ###

set (CXX_FLAGS "-Wall -Wextra -std=c++11")

if (ENABLE_FMOD)
	set (FMOD_FLAGS "lib/libfmodex.so")
endif (ENABLE_FMOD)

if (ENABLE_DEBUG_FLAGS)
	if (ENABLE_OMP)
		set (DEBUG_FLAGS "${DEBUG_FLAGS} -openmp-report1")
	endif (ENABLE_OMP)
	if (CMAKE_COMPILER_IS_GNUCC)
		set (DEBUG_FLAGS "${DEBUG_FLAGS} -ansi -pedantic -Wuninitialized -ftree-vectorizer-verbose=0")
	endif (CMAKE_COMPILER_IS_GNUCC)

	if (${CMAKE_C_COMPILER} MATCHES "icc.*$")
		set (DEBUG_FLAGS "${DEBUG_FLAGS} -Wcheck -vec_report1" )
	endif (${CMAKE_C_COMPILER} MATCHES "icc.*$")
endif (ENABLE_DEBUG_FLAGS)

if(ENABLE_DEBUG_FLAGS_FULL)
	# TODO : check with Intel compiler
	if(CMAKE_COMPILER_IS_GNUCC)
		set(DEBUG_FLAGS "${DEBUG_FLAGS} -W -Wfloat-equal -Wundef")
		set(DEBUG_FLAGS "${DEBUG_FLAGS} -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Waggregate-return")
		set(DEBUG_FLAGS "${DEBUG_FLAGS} -Wmissing-declarations -Wunreachable-code")
		set(DEBUG_FLAGS "${DEBUG_FLAGS} -Winline -Wreorder") # for C++ only
	endif (CMAKE_COMPILER_IS_GNUCC)
endif(ENABLE_DEBUG_FLAGS_FULL)

if (ENABLE_PROFILING)
	set (PROFILING_FLAGS "-pg")
endif (ENABLE_PROFILING)

if (ENABLE_OMP)
	if (CMAKE_COMPILER_IS_GNUCC)
		set(OMP_FLAGS "-fopenmp")
	else (CMAKE_COMPILER_IS_GNUCC)
		set(OMP_FLAGS "-openmp")
	endif (CMAKE_COMPILER_IS_GNUCC)
endif (ENABLE_OMP)

if (ENABLE_OPTIMIZE_FLAGS)
	set(OPTIMIZE_FLAGS "-O3")
	if(CMAKE_COMPILER_IS_GNUCC)
		set(OPTIMIZE_FLAGS "${OPTIMIZE_FLAGS} -march=native -mtune=native")
	endif(CMAKE_COMPILER_IS_GNUCC)
	if (${CMAKE_C_COMPILER} MATCHES "icc.*$")
		set(OPTIMIZE_FLAGS "${OPTIMIZE_FLAGS} -xhost")
	endif(${CMAKE_C_COMPILER} MATCHES "icc.*$")
endif (ENABLE_OPTIMIZE_FLAGS)



# FLAGS for g++
set(CMAKE_CXX_FLAGS "${CXX_FLAGS} ${OPTIMIZE_FLAGS} ${DEBUG_FLAGS} ${PROFILING_FLAGS} ${OMP_FLAGS}")

### CUSTOM COMMAND ###

add_custom_target(doc      COMMAND doxygen ${PROJECT_SOURCE_DIR}/Doxyfile)
add_custom_target(cleanall COMMAND ./clean.sh)


### BUILD PROJECT ###

# Macro for include directories
MACRO(HEADER_DIRECTORIES return_list)
    FILE(GLOB_RECURSE new_list *.h)
    SET(dir_list "")
    FOREACH(file_path ${new_list})
        GET_FILENAME_COMPONENT(dir_path ${file_path} PATH)
        SET(dir_list ${dir_list} ${dir_path})
    ENDFOREACH()
    LIST(REMOVE_DUPLICATES dir_list)
    SET(${return_list} ${dir_list})
ENDMACRO()

# Looking recursively for C files
file(GLOB_RECURSE SRC_FILES ${PROJECT_SOURCE_DIR}/src/*.cc)

# Looking for headers directories
HEADER_DIRECTORIES(HEADER_DIR)

# add the binary tree to the search path for include files for config.h
# include_directories("${PROJECT_BINARY_DIR}" ${HEADER_DIR})
# more restrictive but safer for debugging
include_directories("${PROJECT_BINARY_DIR}" ${PROJECT_SOURCE_DIR}/inc/)

# libraries
link_directories(${PROJECT_SOURCE_DIR}/lib/)
link_libraries (${SDL_LIBRARY})

# add the executable
add_executable(${PROJECT_NAME} ${SRC_FILES})

### POST LINK/FLAGS ###

if(ENABLE_FMOD)
    #32 bits or 64 bits detection for FMOD so library
    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
        target_link_libraries(${PROJECT_NAME} libfmodex64.so)
    else(CMAKE_SIZEOF_VOID_P EQUAL 8)
        target_link_libraries(${PROJECT_NAME} libfmodex.so)
    endif(CMAKE_SIZEOF_VOID_P EQUAL 8)
endif(ENABLE_FMOD)

target_link_libraries(${PROJECT_NAME} m)
